<template>
  <div>
    <el-card style="margin:20px 0">
      <catogory-select :isShowTable="isShowTable" @getCategoryId="getCategoryId"></catogory-select>
    </el-card>
    <el-card>
      <!-- 展示商品属性数据 -->
      <transition name="el-fade-in">
        <div v-show="isShowTable">
          <!-- 添加按钮 -->
          <el-button
            type="primary"
            style="margin-bottom:15px"
            icon="el-icon-plus"
            :disabled="!category3Id"
            @click="addAttr"
          >添加</el-button>
          <!-- form表格 -->
          <el-table :data="attrList" border style="width: 100%">
            <el-table-column prop="date" label="序号" width="80" type="index" align="center"></el-table-column>
            <el-table-column prop="attrName" label="属性名称" width="150"></el-table-column>
            <el-table-column prop="prop" label="属性值列表">
              <!-- 作用域插槽 -->
              <template slot-scope="{row,$index}">
                <el-tag
                  v-for="(attrValue,index) in row.attrValueList"
                  :key="attrValue.id"
                  type="success"
                  style="margin-right:10px"
                >{{ attrValue.valueName }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="address" label="操作" width="200" align="center">
              <template slot-scope="{row,$index}">
                <el-button type="warning" icon="el-icon-edit" size="mini" @click="updateAttr(row)">编辑</el-button>
                <el-popconfirm title="确定删除该属性吗？" @onConfirm="deleteAttr(row)">
                  <el-button
                    slot="reference"
                    type="danger"
                    icon="el-icon-delete"
                    size="mini"
                    style="margin-left:10px"
                  >删除</el-button>
                </el-popconfirm>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </transition>

      <!-- 添加/修改商品属性/属性值数据 -->
      <transition name="el-fade-in">
        <div v-show="!isShowTable">
          <el-form :inline="true" :model="attrInfo" class="demo-form-inline">
            <el-form-item label="属性名">
              <el-input v-model="attrInfo.attrName" placeholder="请输入属性名"></el-input>
            </el-form-item>
          </el-form>
          <!-- 添加属性值事件 -->
          <el-button type="primary" @click="addAttrValue" icon="el-icon-plus" :disabled="!attrInfo.attrName">添加属性</el-button>
          <!-- <el-button @click="isShowTable = !isShowTable">取消</el-button> -->
          <el-table :data="attrInfo.attrValueList" border style="width: 100%; margin:20px 0">
            <el-table-column type="index" label="序号" width="80" align="center"></el-table-column>
            <el-table-column prop="prop" label="属性值名称" width="width">
              <!-- 作用域插槽 -->
              <template v-slot="{row,$index}">
                <!-- input/span切换，实现点击编辑功能 -->
                <el-input
                  v-model="row.valueName"
                  v-if="row.editable"
                  placeholder="请输入属性值"
                  size="mini"
                  @blur="toLook(row)"
                  @keyup.native.enter="toLook(row)"
                  :ref="$index"
                ></el-input>
                <span v-else @click="toEdit(row,$index)" style="display:block">{{row.valueName}}</span>
              </template>
            </el-table-column>
            <el-table-column prop="prop" label="操作" width="width">
              <!-- 作用域插槽 -->
              <template v-slot="{row,$index}">
                <el-popconfirm :title="`确定要删除'${row.valueName}'吗?`" @onConfirm="deleteAttrValue($index)">
                  <el-button type="danger" size="mini" icon="el-icon-delete" slot="reference">删除</el-button>
                </el-popconfirm>
              </template>
            </el-table-column>
          </el-table>
          <el-button type="primary" @click="addOrUpdateAttr" :disabled="attrInfo.attrValueList.length<1">保存</el-button>
          <el-button @click="isShowTable = !isShowTable">返回</el-button>
        </div>
      </transition>
    </el-card>
  </div>
</template>

<script>
import cloneDeep from 'lodash/cloneDeep'
export default {
  name: 'Attrs',
  data () {
    return {
      // 三级列表id
      category1Id: '',
      category2Id: '',
      category3Id: '',
      // 商品属性列表
      attrList: [],
      // 是否显示商品属性表单（默认true显示）,顺便控制三级列表能否选中
      isShowTable: true,
      // 收集新增/修改的属性名需要收集的参数
      attrInfo: {
        // 属性名
        attrName: '',
        // 属性值
        attrValueList: [],
        categoryId: 0,   // 三级分类的id
        categoryLevel: 3  // 告诉服务器是第几级的菜单属性
      },
      // 要删除属性的id
      deleAttrId: ''
    }
  },
  methods: {
    // 获取商品基本属性
    async getAttrList () {
      const result = await this.$api.attrs.reqAttrInfoList(this.category1Id, this.category2Id, this.category3Id)
      if (result.code === 200) {
        this.attrList = result.data
        // console.log(result.data)
        return result.data
      }
    },

    // 添加属性值（添加属性按钮回调）
    addAttrValue () {
      this.attrInfo.attrValueList.push({
        // 属性值id是由服务器返回的
        // 新建属性时没有id，值为undefined，修改属性时使用服务器返回的id
        attrId: this.attrInfo.id,
        // 属性值
        valueName: '',
        // 属性值名称编辑框(默认true)
        // 给每个单独的对象放置一个editable，用户控制查看模式与编辑模式
        editable: true
      })
      // 属性值输入框获得光标
      this.$nextTick(() => {
        this.$refs[this.attrInfo.attrValueList.length - 1].focus()
      })
    },

    // 添加按钮回调
    addAttr () {
      // 页面的显示/隐藏
      this.isShowTable = !this.isShowTable
      // 切换页面后初始化数据
      this.attrInfo = {
        // 属性名
        attrName: '',
        // 属性值
        attrValueList: [],
        // 此时由于category3Id已经生成，此处可以用this.category3Id
        categoryId: this.category3Id,   // 三级分类的id
        categoryLevel: 3  // 告诉服务器是第几级的菜单属性
      }
    },

    // 编辑按钮（修改属性值）回调
    updateAttr (row) {
      // 切换页面
      this.isShowTable = !this.isShowTable
      // 覆盖原有的attrInfo
      // 注意，该赋值属于引用赋值，attrInfo和attrList下某个对象起始是同一个对象，因此修改attrInfo会影响到attrList下的某一个对象
      // 深拷贝一份新的对象赋值给attrInfo
      this.attrInfo = cloneDeep(row)
      // 给attrInfo下的每一个attrValueList下的每一个属性值添加一个editable属性
      // 注意：后添加（初始化时在data中没定义）的属性不是响应式的，要想变成响应式，要使用vm.$set或者this.$set
      this.attrInfo.attrValueList.forEach(item => {
        this.$set(item, 'editable', false)
      })
    },

    // 失去焦点后，编辑框变成阅读模式
    // row = attrValueList数组中新添加的对象
    toLook (row) {
      // 如果输入属性值为空，弹窗提示
      if (row.valueName.trim() == '') {
        this.$message({
          type: 'warning',
          message: '输入值不能为空!'
        })
        return
      }
      // 判断属性名是否重复
      let isRepeat = this.attrInfo.attrValueList.some((item) => {
        // 排他法，除了当前row对象外的其他对象，如果row和其他item有相同的属性名，返回true（存在重复）
        if (row !== item) {
          return row.valueName === item.valueName
        }
      })
      if (isRepeat) {
        this.$message.warning('输入的属性名重复!')
        return
      }
      // console.log(isRepeat)
      // 切换为阅读模式
      row.editable = false
    },

    // 点击属性值名称中指定属性，变成编辑模式
    toEdit (row, index) {
      row.editable = !row.editable
      // console.log(this)
      // 注意，点击span后，变为编辑模式，页面渲染input输入框，但是页面的渲染需要耗时，有可能出现同步代码执行完但渲染未完成的情况
      // 因此需要用到$nextTick
      this.$nextTick(() => {
        // 输入框聚焦
        this.$refs[index].focus()
      })
    },

    // 气泡确认框confirm回调
    deleteAttrValue (index) {
      // 删除指定索引值的属性（这一步没有发请求）
      this.attrInfo.attrValueList.splice(index, 1)
    },

    // 向服务器提交添加/修改的属性、属性值
    async addOrUpdateAttr () {
      // 要求：1.上传的属性值不能有空，采用filter过滤；2.删除掉不需要的editable属性
      this.attrInfo.attrValueList = this.attrInfo.attrValueList.filter(item => {
        // 过滤属性值为空的
        if (item.valueName !== '') {
          // 删除无用的editable属性
          delete item.editable
          return true
        }
      })
      // 将过滤后的数据发送
      try {
        let result = await this.$api.attrs.reqAddOrUpdateAttrInfo(this.attrInfo)
        if (result.code === 200) {
          this.$message.success('保存成功')
          // 保存成功后获取一次新数据
          this.getAttrList()
          // 回到属性页
          this.isShowTable = true
        }
      } catch (error) {
        this.$message.error('保存失败')
      }
    },

    // 删除属性（整条属性）
    async deleteAttr (row) {
      try {
        let result = await this.$api.attrs.reqDeleteAttr(row.id)
        if (result.code === 200) {
          // 提示成功信息
          this.$message.success('删除属性成功')
          // 刷新属性列表
          this.getAttrList()
        }
      } catch (error) {
        this.$message.error('删除属性失败')
      }
    },

    // 获取各级商品id
    getCategoryId ({ categoryId, level }) {
      // 也可以用if...else判断level等级
      // level === 1 ? this.category1Id = categoryId : level === 2 ? this.category2Id = categoryId : this.category3Id = categoryId
      if (level === 1) {
        this.category1Id = categoryId
        // 每次id参数更新都要清空原id
        this.category2Id = ''
        this.category3Id = ''
      } else if (level === 2) {
        this.category2Id = categoryId
        this.category3Id = ''
      } else {
        // 当收到三级菜单的id参数，意味着参数收集完成，开始发送请求获取商品基本属性
        this.category3Id = categoryId
        // console.log('查询商品中...')
        this.getAttrList()
      }
    }
  }
}
</script>

<style>
</style>
